load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
load("@aspect_rules_js//npm:defs.bzl", "npm_link_package")
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@npm//:eslint/package_json.bzl", eslint_bin = "bin")
load("@npm//:prettier/package_json.bzl", prettier = "bin")
load("@poetry//:dependencies.bzl", "dependency")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("//bazel:mongo_js_rules.bzl", "mongo_js_library")
load("//bazel:mongo_src_rules.bzl", "mongo_cc_binary")
load("//bazel/config:render_template.bzl", "render_template")
load("//bazel/install_rules:bolt.bzl", "bolt_instrument", "bolt_optimize")
load("//bazel/install_rules:install_rules.bzl", "TEST_TAGS", "mongo_install")
load("//bazel/toolchains/cc/mongo_linux:mongo_gdb.bzl", "setup_gdb_toolchain_aliases")
load("//bazel/toolchains/cc/mongo_linux:mongo_toolchain.bzl", "setup_mongo_toolchain_aliases")

package(
    default_visibility = ["//visibility:public"],
)

exports_files([
    ".prettierrc",
    "pyproject.toml",
    "poetry.lock",
    ".resmoke_mongo_version.yml",  # containing MONGO_VERSION, generated by Resmoke for tests in Evergreen.
])

npm_link_all_packages(name = "node_modules")

mongo_js_library(
    name = "eslintrc",
    srcs = ["eslint.config.mjs"],
    deps = [
        ":node_modules/@eslint/eslintrc",
        ":node_modules/@eslint/js",
        ":node_modules/eslint-plugin-mongodb",
        ":node_modules/globals",
    ],
)

eslint_bin.eslint_binary(
    name = "eslint",
    data = [
        "//:eslintrc",
    ],
)

prettier.prettier_binary(
    name = "prettier",
    # Include this js_library and its dependencies in the runfiles (runtime dependencies)
    data = ["//:.prettierrc"],
    # Allow the binary to be run outside bazel
    # See more details about this by commenting this out and running `bazel run //:format`
    env = {"BAZEL_BINDIR": "."},
    fixed_args = [
        # `require` statements in the config file will be resolved relative to its location
        # Therefore to make it hermetic, prettier must be pointed at the copy of the config file
        # in the runfiles folder rather than the one in the source folder.
        "--config=\"$$JS_BINARY__RUNFILES\"/$(rlocationpath //:.prettierrc)",
        # default log level is "log" which spams on success
        # https://prettier.io/docs/en/cli.html#--log-level
        # NB: prettier 2 names this loglevel, in prettier 3 it's renamed log-level, see
        # https://prettier.io/blog/2023/07/05/3.0.0.html#cli-1
        "--log-level=warn",
        # Speed this up a little bit with caching
        "--cache",
    ],
)

alias(
    name = "format",
    actual = "//bazel/format:rules_lint_format_wrapper",
)

alias(
    name = "lint",
    actual = "//bazel:lint",
)

alias(
    name = "codeowners",
    actual = "@bazel_rules_mongo//codeowners:codeowners",
)

alias(
    name = "engflow_auth",
    actual = "@bazel_rules_mongo//engflow_auth:engflow_auth",
)

alias(
    name = "mongo-tidy-test",
    actual = "//src/mongo/tools/mongo_tidy_checks/tests:MongoTidyCheck_unittest",
)

setup_mongo_toolchain_aliases()

setup_gdb_toolchain_aliases()

render_template(
    name = "clang_tidy_config",
    srcs = [
        ".clang-tidy.in",
        "//buildscripts:clang_tidy_config_gen.py",
    ],
    cmd = [
        "$(location //buildscripts:clang_tidy_config_gen.py)",
        "--input=$(location .clang-tidy.in)",
        "--output=$(location .clang-tidy)",
    ],
    output = ".clang-tidy",
)

render_template(
    name = "clang_tidy_config_strict",
    srcs = [
        ".clang-tidy.in",
        "//buildscripts:clang_tidy_config_gen.py",
    ],
    cmd = [
        "$(location //buildscripts:clang_tidy_config_gen.py)",
        "--input=$(location .clang-tidy.in)",
        "--output=$(location .clang-tidy.strict)",
        "--warnings-as-errors",
    ],
    output = ".clang-tidy.strict",
)

genrule(
    name = "compiledb",
    srcs = ["compile_commands.json"],
    outs = ["compile_commands_done"],
    cmd = "echo noop > $(location :compile_commands_done)",
)

# This sets up targets for install-wiredtiger and archive-wiredtiger
mongo_install(
    name = "wiredtiger",
    srcs = [
        "//src/third_party/wiredtiger:wt",
    ],
)

# This sets up targets for install-mongod and archive-mongod
mongo_install(
    name = "mongod",
    srcs = [
        "//src/mongo/db:mongod",
    ] + select({
        "@platforms//os:windows": ["@windows_sasl//:bins"],
        "//conditions:default": [],
    }),
)

# This sets up targets for install-mongos and archive-mongos
mongo_install(
    name = "mongos",
    srcs = [
        "//src/mongo/s:mongos",
    ],
)

# This sets up targets for install-mongo and archive-mongo
mongo_install(
    name = "mongo",
    srcs = [
        "//src/mongo/shell:mongo",
    ],
)

# This sets up targets for install-core and archive-core
mongo_install(
    name = "core",
    srcs = [],
    deps = [
        "mongod",
        "mongos",
    ],
)

# This sets up targets for install-devcore and archive-devcore
mongo_install(
    name = "devcore",
    srcs = [],
    deps = [
        "mongo",
        "mongod",
        "mongos",
    ],
)

# This sets up targets for install-mongotest and archive-mongotest
mongo_install(
    name = "mongotest",
    srcs = [
        "//src/mongo/db/query/query_tester:mongotest",
    ],
)

# This sets up targets for install-mongocryptd and archive-mongocryptd
mongo_install(
    name = "mongocryptd",
    srcs = [],
    deps = [
        "//src/mongo/db/modules/enterprise:mongocryptd",
    ],
)

# This reflects the package that actually gets released during packaging. Be careful
# when changing this definition
# This sets up targets for install-dist and archive-dist
mongo_install(
    name = "dist",
    srcs = [
        "//src/mongo/installer/compass:compass_files",
        "//src/mongo/s:mongos",
    ] + select({
        "@platforms//os:windows": ["@local_windows_msvc//:vc_redist_x64"],
        "//conditions:default": [],
    }) + select({
        "//bazel/config:bolt_profile_use_enabled": ["//:bolt_optimized_mongod"],
        "//conditions:default": ["//src/mongo/db:mongod"],
    }),
    package_extract_name = select({
        "//bazel/config:build_enterprise_linux_enabled": "mongodb-linux-{MONGO_ARCH}-enterprise-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_linux_disabled": "mongodb-linux-{MONGO_ARCH}-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_windows_enabled": "mongodb-win32-{MONGO_ARCH}-enterprise-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_windows_disabled": "mongodb-win32-{MONGO_ARCH}-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_mac_enabled": "mongodb-macos-{MONGO_ARCH}-enterprise-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_mac_disabled": "mongodb-macos-{MONGO_ARCH}-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//conditions:default": "mongodb-{MONGO_ARCH}-{MONGO_DISTMOD}-{MONGO_VERSION}",
    }),
    publish_debug_in_stripped = select({
        "@platforms//os:windows": True,
        "//conditions:default": False,
    }),
    deps = [
        "//src/mongo/db/modules/enterprise:dist",
    ],
)

filegroup(
    name = "archive_license_files",
    srcs = [
        "//distsrc:mpl",
        "//distsrc:readme",
        "//distsrc:third_party_notices",
    ] + select({
        "//bazel/config:build_enterprise_enabled": ["//src/mongo/db/modules/enterprise/distsrc:enterprise_license"],
        "//conditions:default": ["//distsrc:community_license"],
    }) + select({
        "//bazel/config:build_enterprise_windows_enabled": ["//src/mongo/db/modules/enterprise/distsrc:windows_notices"],
        "//conditions:default": [],
    }) + select({
        "@platforms//os:macos": ["//etc:mac_plist"],
        "//conditions:default": [],
    }),
)

copy_to_directory(
    name = "mongot_folder",
    srcs = select({
        "//bazel/config:include_mongot_enabled": ["@mongot_localdev//:mongot_binaries"],
        "//conditions:default": [],
    }),
    out = "mongot-localdev",
    include_external_repositories = ["mongot_localdev"],
    tags = [
        "local",
        "no-cache",
    ],
)

# This sets up targets for install-dist-test and archive-dist-test
mongo_install(
    name = "dist-test",
    srcs = [
        "//src/mongo/db:mongotrafficreader",
        "//src/mongo/db/query/query_tester:mongotest",
        "//src/mongo/db/query/search/mongotmock",
        "//src/mongo/db/query/stage_builder/sbe/abt:optimizer_gdb_test_program",
        "//src/mongo/db/storage/key_string:ksdecode",
        "//src/mongo/replay:mongor",
        "//src/mongo/s:mongos",
        "//src/mongo/shell:mongo",
        "//src/mongo/tools/mongobridge_tool:mongobridge",
        "//src/mongo/util:pretty_printer_test_program",
        "//src/third_party/wiredtiger:wt",
    ] + select({
        "@platforms//os:windows": ["@windows_sasl//:bins"],
        "//conditions:default": [],
    }) + select({
        "@platforms//os:linux": ["//src/mongo/db/extension/test_examples:dist_test_extensions"],
        "//conditions:default": [],
    }) + select({
        "//bazel/config:include_mongot_enabled": ["//:mongot_folder"],
        "//conditions:default": [],
    }) + select({
        "//bazel/config:bolt_profile_use_enabled": ["//:bolt_optimized_mongod"],
        "//conditions:default": ["//src/mongo/db:mongod"],
    }),
    pretty_printer_tests = {
        "//src/mongo/util:pretty_printer_test.py": "//src/mongo/util:pretty_printer_test_program",
        "//src/mongo/db/shard_role/lock_manager:lock_gdb_test.py": "//src/mongo/db:mongod",
        "//src/mongo/db/query/stage_builder/sbe/abt:optimizer_gdb_test.py": "//src/mongo/db/query/stage_builder/sbe/abt:optimizer_gdb_test_program",
    },
    try_zstd = True,
    deps = [
        "//src/mongo/db/modules/enterprise:dist-test",
    ],
)

# This sets up targets for install-mongo_crypt and archive-mongo_crypt
mongo_install(
    name = "mongo_crypt",
    srcs = [],
    package_extract_name = "/",
    deps = [
        "//src/mongo/db/modules/enterprise:mongo_crypt",
    ],
)

# This sets up targets for install-mongo_crypt_shlib_test and archive-mongo_crypt_shlib_test
mongo_install(
    name = "mongo_crypt_shlib_test",
    srcs = [],
    deps = [
        "//src/mongo/db/modules/enterprise:mongo_crypt_shlib_test",
    ],
)

# This sets up targets for install-dbtest and archive-dbtest
mongo_install(
    name = "dbtest",
    srcs = [
        "//src/mongo/dbtests:dbtest",
    ],
)

# This sets up targets for install-sdam_json_test and archive-sdam_json_test
mongo_install(
    name = "sdam_json_test",
    srcs = [
        "//src/mongo/client/sdam:sdam_json_test",
    ],
)

# This sets up targets for install-server_selection_json_test and archive-server_selection_json_test
mongo_install(
    name = "server_selection_json_test",
    srcs = [
        "//src/mongo/client/sdam:server_selection_json_test",
    ],
)

# This is because the install system hardlinks files so permission changes end up
# being reflected on the source code version without this copy
copy_file(
    name = "stitch_header",
    src = "//src/mongo/embedded/stitch_support:stitch_support.h",
    out = "copied_files/stitch_support.h",
)

# This sets up targets for install-stitch_support and archive-stitch_support
mongo_install(
    name = "stitch_support",
    srcs = ["//src/mongo/embedded/stitch_support"],
    package_extract_name = "/",
    root_files = {
        "stitch_header": "include/stitch_support/v1/stitch_support",
    },
)

# This sets up targets for install-stitch_support_test and archive-stitch_support_test
mongo_install(
    name = "stitch_support_test",
    testonly = True,
    srcs = [
        "//src/mongo/embedded/stitch_support:stitch_support_test",
    ],
)

# This sets up targets for install-compass and archive-compass
mongo_install(
    name = "compass",
    srcs = ["//src/mongo/installer/compass:compass_files"],
)

[
    mongo_install(
        name = target_name,
        testonly = True,
        srcs = select({
            "//bazel/config:include_autogenerated_targets_enabled": ["//src/mongo/db/modules/enterprise/autogenerated_targets:" + target_name],
            "//conditions:default": [],
        }),
    )
    for target_name in TEST_TAGS.keys()
    if target_name != "mongo_integration_test"
]

# This sets up targets for install-mongo_integration_test and archive-mongo_integration_test
mongo_install(
    name = "mongo_integration_test",
    testonly = True,
    srcs = select({
        "//bazel/config:include_autogenerated_targets_enabled": [
            "//src/mongo/db:mongod",
            "//src/mongo/db/modules/enterprise/autogenerated_targets:mongo_integration_test",
            "//src/mongo/s:mongos",
            "//src/mongo/shell:mongo",
        ],
        "//conditions:default": [],
    }),
)

# This sets up targets for install-mongotmock and archive-mongotmock
mongo_install(
    name = "mongotmock",
    srcs = [
        "//src/mongo/db/query/search/mongotmock",
    ],
)

# This sets up targets for install-extensions and archive-extensions.
mongo_install(
    name = "extensions",
    srcs = [
        "//src/mongo/db/extension/test_examples:dist_test_extensions",
    ],
    package_extract_name = "/",
)

# Pre-built binaries downloaded from an archive-dist-test task.
filegroup(
    name = "installed-dist-test",
    srcs = glob([
        "dist-test/**",
    ]),
)

# Jstests generated by jstestfuzz or downloaded from an Evergreen task.
filegroup(
    name = "jstestfuzz_generated_tests",
    srcs = glob([
        "jstestfuzz/out/*.js",
    ]),
)

# Multiversion binaries downloaded using db-contrib-tool, setting --linkDir to this directory.
filegroup(
    name = "multiversion_binaries",
    srcs = glob([
        "multiversion_binaries/**",
    ]),
)

# Resmoke config files generated by mongo-task-generator
filegroup(
    name = "generated_resmoke_config",
    srcs = glob([
        "generated_resmoke_config/**",
    ]),
)

# This sets up targets for install-mongor and archive-mongor
mongo_install(
    name = "mongor",
    srcs = [
        "//src/mongo/replay:mongor",
    ],
)

sh_binary(
    name = "scip-clang",
    srcs = ["//bazel:run_under_working_dir.sh"],
    data = ["@scip-clang//file"],
    env = {
        "BINARY_PATH": "$(location @scip-clang//file)",
    },
)

sh_binary(
    name = "scip-src",
    srcs = ["//bazel:run_under_working_dir.sh"],
    data = ["@scip-src//file"],
    env = {
        "BINARY_PATH": "$(location @scip-src//file)",
    },
)

py_binary(
    name = "gen_dts",
    srcs = [
        "//buildscripts/idl:gen_dts",
    ],
    deps = [
        dependency(
            "pyyaml",
            group = "core",
        ),
        dependency(
            "pymongo",
            group = "core",
        ),
    ],
)

# Unused for now due to instrumented mongod crashing on machines slightly different than the one
# it gets built on
bolt_instrument(
    name = "bolt_instrumented_mongod",
    binary_to_instrument = "//src/mongo/db:mongod",
    exec_properties = {
        "no-cache": "1",
        "no-remote": "1",
        "local": "1",
    },
    instrumentation_output_file = "/tmp/mongod_bolt/mongod.fdata",
    target_compatible_with = select({
        "//bazel/config:bolt_profile_generate_enabled": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
)

bolt_optimize(
    name = "bolt_optimized_mongod",
    binary_to_optimize = "//src/mongo/db:mongod",
    exec_properties = {
        "no-cache": "1",
        "no-remote": "1",
        "local": "1",
    },
    perf_data = "@bolt_data//:bolt_fdata",
    target_compatible_with = select({
        "//bazel/config:bolt_profile_use_enabled": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
)

filegroup(
    name = "clang_tidy_config_files",
    srcs = [
        "//src/mongo/db/modules/enterprise/src/streams:clang_tidy_config",
        "//src/mongo/db/modules/enterprise/src/streams/commands/streams_ops_idl:clang_tidy_config",
    ],
)

# This target only does anything meaningful if you pass pgo_profile_url and bolt_profile_url
# as repo_envs to the build
mongo_install(
    name = "profile_data",
    srcs = ["@bolt_data//:created_bolt_fdata"] + select({
        "//bazel/config:compiler_type_gcc": ["created_pgo_gcda"],
        "//bazel/config:compiler_type_clang": ["@pgo_data//:created_clang_pgo_files"],
        "//conditions:default": [],
    }),
)

pkg_tar(
    name = "created_pgo_gcda",
    srcs = ["@pgo_data//:created_gcc_pgo_files"],
    extension = "tgz",
    package_dir = "mongod_perf",
)
